using GameServer.ShootingGame.RenderableClasses;
using GameServer.ShootingGame.WeaponsClasses.LaunchProfiles;
namespace GameServer.ShootingGame.WeaponsClasses
{


    public class WeaponInfo
    {

        public LaunchProfiles.LaunchProfiles launchprofile;
        public int ammoMax;
        private int ammoCount;
        public double ordinanceSpeed;
        public double damage;
        public int coolDownTime;
        private int coolDownTimeCount;
        public int clipSize;
        private int clipCount;
        public int ammoPerShot;
        private double accuracy;
        private double minAccuracy;
        private double maxAccuracy;
        private double accuracyDegradeRate;
        private double accuracyRecoverRate;
        public double spinUpTime;
        private double spinUpTimeCount;
        public int chargeMax;
        private int chargeRate; //amount to charge per millisecond the primary mouse button is depressed.
        private int chargeCount;
        private double turningRate; //in degrees
        private int numCoolDownSteps;
        /// <summary>
        /// A sample instsance of the Ordinance type to clone every time the Weapon fires.
        /// </summary>
        public Ordinance ordinanceSample;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="launchProfile"></param>
        /// <param name="ordinanceSpeed"></param>
        /// <param name="maxAmo"></param>
        /// <param name="ammoCount"></param>
        /// <param name="damage"></param>
        /// <param name="coolDownTime"></param>
        /// <param name="clipSize">Default = int.MaxValue</param>
        /// <param name="ammoPerShot">Default = 1</param>
        /// <param name="minAccuracy">Default = 1</param>
        /// <param name="maxAccuracy">Default = 1</param>
        /// <param name="accuracyDecreaseRate">Default = 0</param>
        /// <param name="accuracyIncreaseRate">Default = 1</param>
        /// <param name="spinUpTime">Default = 0</param>
        /// <param name="chrageMax">Default = 0</param>
        /// <param name="chargeRate">Default = 0</param>
        /// <param name="turnRate">Default = 0</param>
        public WeaponInfo(LaunchProfiles.LaunchProfiles launchProfile, double ordinanceSpeed, int maxAmo,
                        int ammoCount, double damage, int coolDownTime, int clipSize, int ammoPerShot,
                        double minAccuracy, double maxAccuracy, double accuracyDecreaseRate,
                        double accuracyIncreaseRate, double spinUpTime, int chargeMax, int chargeRate, double turnRate)
        {
            this.launchprofile = launchProfile;

            this.ammoMax = maxAmo;
            this.ammoCount = ammoCount;
            this.ordinanceSpeed = ordinanceSpeed;
            this.damage = damage;
            this.coolDownTime = coolDownTime;
            this.coolDownTimeCount = 0;
            this.clipSize = clipSize;
            this.clipCount = clipSize;
            this.ammoPerShot = ammoPerShot;
            this.minAccuracy = minAccuracy;
            this.maxAccuracy = maxAccuracy;
            this.Accuracy = maxAccuracy;
            this.accuracyDegradeRate = accuracyDecreaseRate;
            this.accuracyRecoverRate = accuracyIncreaseRate;
            this.spinUpTime = spinUpTime;
            this.spinUpTimeCount = 0;
            this.chargeMax = chargeMax;
            this.ChargeRate = chargeRate;
            this.chargeCount = 0;
            this.TurningRate = turnRate;
        }

        public int ClipCount
        {
            get
            {
                return clipCount;
            }
        }

        public bool ShotsFired()
        {
            if (clipCount > ammoPerShot)
            {
                clipCount -= ammoPerShot;
                ammoCount -= ammoPerShot;
                Accuracy -= accuracyDegradeRate;
                numCoolDownSteps = 0;
                return true;
            }
            return false;
        }

        public int AmmoCount
        {
            get
            {
                return ammoCount;
            }
            set
            {
                if (value > ammoMax)
                    value = ammoMax;
                ammoCount = value;
            }
        }

        public int CoolDownTimeCount
        {
            get
            {
                return coolDownTimeCount;
            }
            set
            {
                coolDownTimeCount = value;
                if (coolDownTimeCount < 0)
                {
                    if (accuracy < maxAccuracy)
                    {
                        var numCoolDownSteps_Now = (-coolDownTimeCount) / (int)coolDownTime;
                        if (numCoolDownSteps_Now > numCoolDownSteps)
                        {
                            numCoolDownSteps = numCoolDownSteps_Now;
                            accuracy += accuracyRecoverRate;
                        }
                    }
                }
            }
        }

        public double Accuracy
        {
            get
            {
                return accuracy;
            }
            set
            {
                accuracy = value;
                if (accuracy < minAccuracy)
                    accuracy = minAccuracy;
                else
                    if (accuracy > maxAccuracy)
                        accuracy = maxAccuracy;
            }
        }

        public double MaxAccuracy
        {
            get
            {
                return maxAccuracy;
            }
            set
            {
                maxAccuracy = value;
                if (maxAccuracy < 0)
                    maxAccuracy = 0.1;
                else
                    if (maxAccuracy > 1)
                        maxAccuracy = 1;
            }
        }

        public double MinAccuracy
        {
            get
            {
                return minAccuracy;
            }
            set
            {
                minAccuracy = value;
                if (minAccuracy < 0)
                    minAccuracy = 0.1;
                else
                    if (minAccuracy > 1)
                        minAccuracy = 1;
            }
        }

        public double SpinUpTimeCount
        {
            get
            {
                return spinUpTimeCount;
            }
            set
            {
                spinUpTimeCount = value;
                if (spinUpTimeCount < 0)
                    spinUpTimeCount = 0;
            }
        }

        public int ChargeRate
        {
            get
            {
                return chargeRate;
            }
            set
            {
                if (value > chargeMax)
                    value = chargeMax;
                chargeRate = value;
            }
        }

        public double TurningRate
        {

            get
            {
                return turningRate;
            }
            set
            {
                turningRate = value;
                if (turningRate < 0)
                    turningRate = 0;
                else
                    if (turningRate >= 360)
                        turningRate = turningRate % 360;
            }
        }


    }
}